package com.fzu.geometa.auth.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.fzu.geometa.auth.model.dto.CaptchaValidation;
import com.fzu.geometa.auth.util.RedisKeyUtil;
import com.fzu.geometa.common.model.dto.RestResponse;
import com.google.code.kaptcha.Producer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class CaptchaController {
    @Autowired
    private Producer kaptchaProducer;

    @Autowired
    private RedisTemplate redisTemplate;

    // 上一次生成的时间
    private long lastTime;


    @GetMapping(path = "/captcha/get")
    public RestResponse getCaptcha(HttpServletResponse response) {
        // 一秒只最多 2 个
        if (System.currentTimeMillis() - lastTime < 500) {
            return RestResponse.validFail("刷新过于频繁");
        }

        // 生成验证码
        String text = kaptchaProducer.createText();
        BufferedImage image = kaptchaProducer.createImage(text);

        Map<String, String> captcha = new HashMap<>();
        String captchaId = UUID.randomUUID().toString();
        captcha.put("id", captchaId);
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            // 将验证码图片写入到字节数组输出流中
            ImageIO.write(image, "png", outputStream);
            // 对字节数组进行 Base64 编码并转换为字符串
            captcha.put("image", Base64.getEncoder().encodeToString(outputStream.toByteArray()));
            lastTime = System.currentTimeMillis();
        } catch (IOException ex) {
            return RestResponse.validFail(ex.getMessage());
        }

        String key = RedisKeyUtil.getKaptchaKey(captchaId);
        // 存入 Redis，有效期两分钟
        redisTemplate.opsForValue().set(key,text,120, TimeUnit.SECONDS);
        return RestResponse.success(captcha);
    }

    @PostMapping(path = "captcha/verify")
    public RestResponse verifyCaptcha(CaptchaValidation captcha) {
        if (ObjectUtil.isNull(captcha)) {
            return RestResponse.validFail("验证信息为空");
        }
        String captchaId = captcha.getId();
        if (StrUtil.isBlank(captchaId)) {
            return RestResponse.validFail("验证 id 为空");
        }
        String captchaValue = captcha.getValue();
        if (StrUtil.isBlank(captchaValue)) {
            return RestResponse.validFail("输入验证码内容为空");
        }

        String key = RedisKeyUtil.getKaptchaKey(captchaId);
        String realValue = (String) redisTemplate.opsForValue().get(key);

        if (ObjectUtil.isNull(realValue)) {
            return RestResponse.validFail("验证码已失效");
        }

        if (StrUtil.equals(captchaValue,realValue)) {
            // 验证成功，验证码失效
            redisTemplate.delete(key);
            return RestResponse.success();
        } else {
            return RestResponse.validFail("验证码错误");
        }

    }
}
